/*
 * lcd.c
 *
 *  Created on: Jun 15, 2011
 *      Author: ben
 */
#include <avr/io.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>

#include "s_glcd.h"
#include "usart_2.h"
#include "em_406a.h"

void onWriteChar(char data)
{
	usart_send_byte_2(data);
}

void onWriteString(char *data)
{
	usart_send_string_2(data);
}

void onWriteDouble(double data)
{
	usart_send_double_2(data);
}

void onWriteCmd(char data)
{
	usart_send_byte_2(data);
}

void onWriteStatus(char *data)
{
	onClearStatus();
	onSetX(LEFT + 2);
	onSetY(BOTTOM-2);
	int length = strlen(data);
	if (length > MAX_CHAR_LEN - 1)
		length = MAX_CHAR_LEN - 1;
	for (int i = 0; i < length; i++)
		onWriteChar(data[i]);

}

int onWriteStatusPrintF(char data, FILE *stream)
{
	onSetX(LEFT);
	onSetY(Y_MIDDLE - 3*CHAR_HEIGHT);
	if (data == '\n') onWriteStatusPrintF('\r', stream);
		onWriteChar(data);
	return 0;
}

void onMainMenu()
{
	onClearScreen();
	onSetX(0x25);
	onWriteString("Main Menu");

	onSetX(0x00);
	onSetY(Y_MIDDLE + 2*CHAR_HEIGHT);
	onWriteString("GPS");

	onSetX(0x00);
	onSetY(Y_MIDDLE - 2*CHAR_HEIGHT);
	onWriteString("Temp");

	onSetX(X_MAX - 3*CHAR_LENGTH);
	onSetY(Y_MIDDLE + 2*CHAR_HEIGHT);
	onWriteString("Car");

	onSetX(X_MAX - 4*CHAR_LENGTH);
	onSetY(Y_MIDDLE - 2*CHAR_HEIGHT);
	onWriteString("More");

	onDrawStatusBox();
}

void onGPSMenu()
{
	onClearScreen();

	onSetX(LEFT);
	onWriteString("Back");

	onSetX(X_MIDDLE - 1.5*CHAR_LENGTH);
	onWriteString("GPS");

	onSetX(RIGHT - 4*CHAR_LENGTH);
	onWriteString("More");

	onSetX(LEFT);
	onSetY(Y_MIDDLE + 1*CHAR_HEIGHT);
	onWriteString("LAT: ");

	onSetX(LEFT);
	onSetY(Y_MIDDLE - 1*CHAR_HEIGHT);
	onWriteString("LON: ");

	onDrawStatusBox();
}

void onTempMenu(void)
{
	onClearScreen();

	onSetX(LEFT);
	onWriteString("Back");

	onSetX(X_MIDDLE - 2*CHAR_LENGTH);
	onWriteString("Temp");

	onSetX(LEFT);
	onSetY(Y_MIDDLE + 1*CHAR_HEIGHT);
	onWriteString("Outside Temp: ");

	onDrawStatusBox();
}

void onCarMenu(void)
{
	onClearScreen();

	onSetX(LEFT);
	onWriteString("Back");

	onSetX(X_MIDDLE - 1.5*CHAR_LENGTH);
	onWriteString("Car");

	onSetX(LEFT);
	onSetY(Y_MIDDLE + 1*CHAR_HEIGHT);
	onWriteString("RPM: ");

	onSetX(LEFT);
	onSetY(Y_MIDDLE - 1*CHAR_HEIGHT);
	onWriteString("SPEED: ");

	onDrawStatusBox();
}

void onAmpMenu(void)
{
	onDrawStatusBox();

}

void onMainMore(void)
{
	onClearScreen();
	onSetX(0x25);
	onWriteString("Main Menu(2)");

	onSetX(0x00);
	onSetY(Y_MIDDLE + 2*CHAR_HEIGHT);
	onWriteString("Back");

	onSetX(0x00);
	onSetY(Y_MIDDLE - 2*CHAR_HEIGHT);
	onWriteString("Conf");

	onSetX(X_MAX - 3*CHAR_LENGTH);
	onSetY(Y_MIDDLE + 2*CHAR_HEIGHT);
	onWriteString("Amp");

	onDrawStatusBox();
}

void onMainConf(void)
{

	onDrawStatusBox();
}

void onGPSMore(void)
{
	onClearScreen();

	onSetX(LEFT);
	onWriteString("Back");

	onSetX(X_MIDDLE - 4*CHAR_LENGTH);
	onWriteString("GPS Config");

	onSetX(LEFT);
	onSetY(Y_MIDDLE + 1*CHAR_HEIGHT);
	onWriteString("#1: ");

	onSetX(LEFT);
	onSetY(Y_MIDDLE - 1*CHAR_HEIGHT);
	onWriteString("#2: ");

	onDrawStatusBox();
}

void onAmpMore(void)
{

	onDrawStatusBox();
}

void onSetLCDLatitude(double lat, char NS)
{
	onSetX(LEFT + 4*CHAR_LENGTH);
	onSetY(Y_MIDDLE + 1*CHAR_HEIGHT);
	onWriteDouble(lat);
	onWriteString(" ");
	onWriteChar(NS);
}

void onSetLCDLongitude(double lon, char EW)
{
	onSetX(LEFT + 4*CHAR_LENGTH);
	onSetY(Y_MIDDLE - 1*CHAR_HEIGHT);
	onWriteDouble(lon);
	onWriteString(" ");
	onWriteChar(EW);
}

void onLoadingScreen(void)
{
	onClearArea(X_MIDDLE - 4*CHAR_LENGTH, Y_MIDDLE - 2*CHAR_HEIGHT,
				X_MIDDLE + 4*CHAR_LENGTH, Y_MIDDLE + 1*CHAR_HEIGHT);
	onSetX(X_MIDDLE - 3*CHAR_LENGTH);
	onSetY(Y_MIDDLE);
	onWriteString("Loading");
	onDrawBox(X_MIDDLE - 4*CHAR_LENGTH, Y_MIDDLE - 2*CHAR_HEIGHT,
			  X_MIDDLE + 4*CHAR_LENGTH, Y_MIDDLE + 1*CHAR_HEIGHT);
}

void onLoadingScreenBar(void)
{
	onLoadingScreen();
	onDrawLoadingBar();
}

void onClearScreen()
{
	onWriteCmd(CTL);
	onWriteCmd(CLR);
}

void onSetX(char x_spot)
{
	onWriteCmd(CTL);
	onWriteCmd(SET_X);
	onWriteCmd(x_spot);
}

void onSetY(char y_spot)
{
	onWriteCmd(CTL);
	onWriteCmd(SET_Y);
	onWriteCmd(y_spot);
}

void onSetXY(char x_spot, char y_spot)
{
	onSetX(x_spot);
	onSetY(y_spot);
}

void onDrawLine(char x1, char y1, char x2, char y2)
{
	onWriteCmd(CTL);
	onWriteCmd(DRAW_LINE);
	onWriteCmd(x1);
	onWriteCmd(y1);
	onWriteCmd(x2);
	onWriteCmd(y2);
	onWriteCmd(0x01);
}

void onDrawBox(char x1, char y1, char x2, char y2)
{
	onWriteCmd(CTL);
	onWriteCmd(DRAW_BOX);
	onWriteCmd(x1);
	onWriteCmd(y1);
	onWriteCmd(x2);
	onWriteCmd(y2);
}

void onClearLine(char y_coord)
{
	onSetX(LEFT);
	onSetY(y_coord);
	for (int i = 0; i < MAX_CHAR_LEN; i++)
	{
		onWriteChar(0x20);
	}
}

void onClearArea(char x1, char y1, char x2, char y2)
{
	onWriteCmd(CTL);
	onWriteCmd(ERASE_BLOCK);
	onWriteCmd(x1);
	onWriteCmd(y1);
	onWriteCmd(x2);
	onWriteCmd(y2);
}

void onClearStatus(void)
{
	onWriteCmd(CTL);
	onWriteCmd(ERASE_BLOCK);
	onWriteCmd(0x01);
	onWriteCmd(0x00);
	onWriteCmd(0x7E);
	onWriteCmd(0x07);
}

void onDrawStatusBox(void)
{
	onDrawLine(0x00, 0x08, 0x7F, 0x08);
	onDrawLine(0x00, 0x01, 0x00, 0x08);
	onDrawLine(0x7F, 0x01, 0x7F, 0x08);
}

void onDrawLoadingBar(void)
{
	onDrawBox(X_MIDDLE - 3*CHAR_LENGTH, Y_MIDDLE - 1.5*CHAR_HEIGHT-1,
			  X_MIDDLE + 3*CHAR_LENGTH, Y_MIDDLE - 1.5*CHAR_HEIGHT + 1);
}

void onUpdateLoadingBar(int cnt)
{
//	float drawAmount = ((percent / 100) * 42);
	if (cnt > 42)
		cnt = 42;
	char x = 0x2b;
	char y = 0x14;
	for (int i = 0; i < cnt; i++)
	{
		onSetPixel(x, y);
		x++;
	}
}

void onSetPixel(char x, char y)
{
	onWriteCmd(CTL);
	onWriteCmd(SET_PX);
	onWriteCmd(x);
	onWriteCmd(y);
	onWriteCmd(0x01);
}
